package cn.com.pansky.action.bank;

import java.nio.charset.Charset;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang3.StringUtils;
import org.apache.commons.net.util.Base64;
import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;

import cn.com.pansky.payment.PayConf;
import cn.com.pansky.util.AppUtils;
import cn.com.pansky.util.Crypto;
import cn.com.pansky.util.HttpClientUtil;

import com.alibaba.fastjson.JSONObject;
import com.google.common.base.Predicate;
import com.google.common.collect.Maps;

/**
 * 建设银行订单查询
 * 
 * @author xiangli
 *
 */
public class JHQueryOrder {

	// 查询地址
	private String url;

	// 消息版本号 ( 2.0)
	private String version = PayConf.QUE_VERSION;

	// 字符编码(必填): GBK或UTF-8
	private String charset = PayConf.CHARSET;

	// 签名方法(必填): MD5
	private String signMethod = PayConf.SIGNMETHOD;

	// 支付接口类型 个人支付：B2C 企业支付：B2B
	private String payType = "B2C";

	// 交易类型(必填): 01—消费交易查询
	private String transType = "01";

	// 商户编号(必填): 与清算平台签约时，由清算平台统一分配。最长30位
	private String merId = PayConf.MERID;

	// 商户密钥
	private String signKey = PayConf.SIGNKEY;

	// 商户订单号(可选，商户的交易定单号,由商户网站生成,最大长度32)
	private String orderNumber;

	// 交易查询时间 （必选，格式：yyyyMMddHHmmss。)
	private String queryTime;

	// 原始交易流水号(可选)
	private String qid;

	public JHQueryOrder(String queryurl, String merId, String signKey,
			String orderNumber, String queryTime, String qid) {
		this.url = queryurl;
		this.merId = merId;
		this.signKey = signKey;
		this.orderNumber = orderNumber;
		this.queryTime = queryTime;
		this.qid = qid;
	}

	/**
	 * 订单查询.
	 * <p>
	 * 进行订单查询请求时，商户订单号,交易时间,原始流水号不能全部为空。
	 * <p>
	 */
	public JSONObject query() {
		Map<String, String> paramMap = new HashMap<String, String>();
		paramMap.put("version", version);
		paramMap.put("charset", charset);
		paramMap.put("signMethod", signMethod);
		paramMap.put("payType", payType);
		paramMap.put("transType", transType);
		paramMap.put("merId", merId);
		paramMap.put("orderNumber", orderNumber);
		paramMap.put("queryTime", queryTime);
		paramMap.put("qid", qid);

		// 过滤掉为空的键
		// paramMap = Maps.filterEntries(paramMap, entry ->
		// StringUtils.isNotBlank(entry.getValue()));
		paramMap = Maps.filterEntries(paramMap,
				new Predicate<Map.Entry<String, String>>() {
					@Override
					public boolean apply(Map.Entry<String, String> entry) {
						return StringUtils.isNotBlank(entry.getValue());
					}
				});

		// 签名信息
		String sign = AppUtils.signBeforePost(paramMap, signKey, charset);// 生成加密签名串

		paramMap.put("sign", sign);

		System.out.println("向清算平台发送交易查询请求:" + paramMap.toString());// 请求报文
		String httpPost = HttpClientUtil.httpPost(url, paramMap, charset);
		System.out.println("清算平台同步响应:" + httpPost);// 返回的响应报文

		return readStringXml(httpPost, signKey, charset);
	}

	/**
	 * 响应报文解析
	 *
	 * @param xml
	 * @param signKey
	 * @return String
	 */

	private JSONObject readStringXml(String xml, String signKey, String charset) {

		JSONObject json = new JSONObject();
		if (StringUtils.isBlank(xml))
			return null;

//		List<String> strings = com.google.common.base.Splitter.on('&').splitToList(xml);
		String[] strings = xml.split("&");
		List<String> list = Arrays.asList(strings);
		
		if (list.size() != 2)
			return null;

		String content = new String(new Base64().decode(StringUtils
				.substringAfter(list.get(0), "=")), Charset.forName(charset));
		String sign = StringUtils.substringAfter(list.get(1), "=");

		String calcSign = Crypto.GetMessageDigest(
				content + "&"
						+ Crypto.GetMessageDigest(signKey, "MD5", charset),
				"MD5", charset);
		if (!calcSign.equals(sign)) {
			System.out.println("签名不正确");
			return null;
		}
		try {
			Document doc = DocumentHelper.parseText(content);

			Element rootElt = doc.getRootElement();
			String respCode = rootElt.elementText("respCode");
			if ("00".equals(respCode)) {
				System.out.println("单笔查询成功：");
				System.out.println(content);
				Element e = rootElt.element("queryorder");
				json.put("orderAmount", e.elementText("orderAmount"));
				json.put("orderNumber", e.elementText("orderNumber"));
				json.put("qid", e.elementText("qid"));
				json.put("state", e.elementText("state"));
				json.put("AAE010", "999999");
				json.put("bankType", "JH");

			} else {
				System.out.println(respCode);
			}
		} catch (Exception e) {
			System.out.println("返回的XML文件解析错误!" + e);
		}
		return json;
	}

	public static void main(String[] args) {
		String transType = PayConf.PAY_TRANSTYPE;
		String queryurl = PayConf.JSPT_QUERY_URL;
		String merId = PayConf.MERID;
		String signKey = PayConf.SIGNKEY;
		String orderNumber = "49673504";
		String queryTime = "20170428083900";
		String qid = "";

		// 清算平台查询
		if ("01".equals(transType)) {
			JHQueryOrder queryOrder = new JHQueryOrder(queryurl, merId,
					signKey, orderNumber, queryTime, qid);
			queryOrder.query();
		}
	}

}
